const ws = require('nodejs-websocket');
const SerialPort = require('serialport');
const { C51cfg } = require('../web.config');
const moment = require('moment');
const schedule = require('node-schedule');
const ZK_SENSORDATA = require('../model/ZK_SENSORDATA');
const Public = require('../common/Public');
const DataAccess = require('../common/DataAccess');
const OperationEnum = require('../common/OperationEnum');
const ds = new DataAccess();

class C51Helper {
    constructor(config) {
        config = config || C51cfg;
        this.wsserver = null;
        this.serialport = null;
        this.logs = [];
        this.message = "";
        SerialPort.list((err, ports) => {
            if (ports.length === 0) {
                console.log("\x1B[36m%s\x1B[0m", "请正确连接硬件设备");
                console.log("\x1B[31m%s\x1B[0m", "暂无可用串口，无法侦听" + config.comName + "串口");
                return false;
            }
            ports.forEach((port, index) => {
                if (port.comName.toUpperCase() === config.comName.toUpperCase()) {
                    config.comName = port.comName;
                    this.wsserver = ws.createServer((conn, res) => {
                        console.log("创建连接成功");
                        conn.sendText(JSON.stringify({
                            msg: "[" + moment().format('YYYY-MM-DD HH:mm:ss') + "]  远程监控连接成功,正在为您推送信息"
                        }));
                        conn.on("text", (data) => { this.OnWsMessage(conn, data); });
                        conn.on("close", () => { console.log("连接已关闭"); });
                        conn.on("error", () => { });
                    }).listen(config.wsPort);
                    this.serialport = new SerialPort(config.comName, {
                        baudRate: config.baudRate,
                        autoOpen: false
                    });
                    this.serialport.open((err) => {
                        if (err) {
                        } else {
                            this.StartSchedule();
                        }
                    });
                    this.serialport.on("data", (buf) => { this.OnSrMessage(buf); });
                }
            });
        });
    }


    /**
     * 接收到websocket信息触发(下发指令)
     * @param {*} conn 
     * @param {*} data 协商好的命令
     */
    OnWsMessage(conn, data) {
        try {
            //this.serialport.write(new Buffer(data, "hex"));
            this.serialport.write(data, (err, res) => {
                if (err) {
                    conn.sendText(JSON.stringify({
                        msg: "[" + moment().format('YYYY-MM-DD HH:mm:ss') + "]  指令发送异常"
                    }));
                } else {
                    conn.sendText(JSON.stringify({
                        msg: "[" + moment().format('YYYY-MM-DD HH:mm:ss') + "]  指令发送成功"
                    }));
                }
            });
        } catch (err) { }
    }



    /**
     * 接收到串口数据触发(群发信息)
     * @param {*} buf (湿度,温度,光照,灯泡总数,亮灯数量,水泵状态)
     */
    OnSrMessage(buf) {
        let str = buf.toString();
        if (str.indexOf("$") === 0) {
            str = str.substring(1, str.length);
            this.message = "";
        }
        this.message = this.message + str;
        if (this.message.indexOf("#") === this.message.length - 1) {
            this.message = this.message.substring(0, this.message.length - 1);
            let record = this.message.split(",");
            if (record.length !== 4) { return false; }
            let sensor = new ZK_SENSORDATA({
                ZK_ID: Public.BuildCode(),
                ZK_TEMP: record[0],
                ZK_HUMI: record[1],
                ZK_ILLU: record[2],
                ZK_TIME: new Date(),
                EB_ISDELETE: "0",
                EB_CREATEBY: "cmd",
                EB_LASTMODIFYBY: "cmd"
            });
            this.logs.push(sensor);
            let time = moment(sensor.ZK_TIME).format('YYYY-MM-DD HH:mm:ss');
            let socketmsg = [];
            socketmsg.push("[" + time + "] ");
            socketmsg.push("湿度:" + sensor.ZK_HUMI + "%");
            socketmsg.push("温度:" + sensor.ZK_TEMP + "℃");
            socketmsg.push("光照:" + sensor.ZK_ILLU + " lx");
            this.wsserver.connections.forEach(conn => {
                try {
                    conn.sendText(JSON.stringify({
                        humi: sensor.ZK_HUMI,
                        temp: sensor.ZK_TEMP,
                        illu: sensor.ZK_ILLU,
                        time: time,
                        ltotal: 0,
                        ontotal: 0,
                        working: Number.parseInt(record[3], 10) === 1,
                        msg: socketmsg.join("  ")
                    }));
                } catch (err) { }
            });
            console.log("传感器数据：", this.message);
        }
    }


    /**
     * 开启任务调度
     */
    StartSchedule() {
        schedule.scheduleJob("30 * * * * *", () => {
            let total = this.logs.length;
            if (total > 0) {
                if (C51cfg.upload) {
                    ds.TransRunQuery(Public.OperationSQLParams(this.logs, OperationEnum.Create)).then(flag => {
                        this.logs.splice(0, total);
                        console.log("\x1B[36m%s%s\x1B[0m", "调度任务：", flag ? "记录保存成功" : "记录保存失败");
                    }).catch(err => {
                        this.logs.splice(0, total);
                        console.log("记录保存异常");
                    });
                } else {
                    this.logs.splice(0, total);
                    console.log("\x1B[36m%s\x1B[0m", "调度任务：清空记录取消删除");
                }

            }
        });
    }


}


module.exports = C51Helper;